package com.kingdee.shr.dataMapHelper;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.shr.custom.utils.PersonDataUtils;
import com.kingdee.shr.entity.HRPersonal;
import com.kingdee.shr.entity.HRTransferForm4Cadre;
import com.kingdee.util.StringUtils;

/**
 * Title: EntityMaker
 * <p>
 * Description: 根据员工参数生成对应人事表单的实体类
 * 
 * @author fei_tong
 * @date 2019-3-25 & 下午03:10:03
 * @since V1.0
 */
public class EntityMaker {
	private Logger log = Logger.getLogger(EntityMaker.class);

	/**
	 * 限制为单例
	 */
	private EntityMaker() {
		if (EntityMakerHolder.entityMaker != null) {
			log.error("EntityMaker类单例已存在，不能再实例化");
			throw new IllegalStateException();
		}
	}

	/**
	 * 获取单例方法
	 * 
	 * @return
	 */
	public static EntityMaker getEntityMaker() {
		return EntityMakerHolder.entityMaker;
	}

	/**
	 * @author tony-huawei 单例静态实例内部类
	 */
	private static class EntityMakerHolder {
		private static EntityMaker entityMaker = new EntityMaker();
	}

	/**
	 * 根据人员personId实例化实体类HRPersonal的方法
	 * 
	 * @param ctx
	 * @param personId
	 * @param callChain
	 * @return 如果出错则返回null，错误信息会记录到日志中
	 */
	public HRPersonal makeHRPersonal(Context ctx, String personId,
			String callChain) {
		if (callChain == null)
			callChain = "";
		callChain += "根据人员personId实例化实体类HRPersonal的方法：";

		if (StringUtils.isEmpty(personId)) {
			callChain += "员工内码personId参数为null或空";
			log.error(callChain);
			return null;
		}
		HRPersonal person = new HRPersonal();
		Map<String, Object> baseInfo = null;
		try {
			baseInfo = PersonDataUtils.getPersonBaseInfoById(personId);
		} catch (BOSException e) {
			callChain += "查询个人基本信息表实体类个人基本数据的方法执行异常：" + e;
			log.error(callChain);
			return null;
		}
		;
		SimpleDateFormat sdf = null;
		if (baseInfo != null) {
			Object nameO= baseInfo.get("name");
			if (nameO!=null) {
				person.setName((String) nameO);
			}
			Object genderO=baseInfo.get("gender");
			if (genderO!=null) {
				person.setGender(("1".equals(genderO.toString())) ? "，男" : "，女");
			}
			Object ethnicityO=baseInfo.get("folk");
			if (ethnicityO!=null) {
				person.setEthnicity("，"+(String) ethnicityO);
			}
			Object birthdayO=baseInfo.get("birthday");
			Date birth;
			if (birthdayO!=null) {
				birth = (Date) birthdayO;
				sdf = new SimpleDateFormat("yyyy.MM");
				String Birth = sdf.format(birth);
				sdf = null;
				String yearStr=Birth.substring(0, Birth.indexOf('.'));
				String monthStr=Birth.substring(Birth.indexOf('.')+1, Birth.length());
				person.setBirthYear("，"+yearStr);
				person.setBirthMonth(monthStr);
			}
			Object homePlaceO=baseInfo.get("homeplace");
			if (homePlaceO!=null) {
				person.setHomePlace("，"+(String) homePlaceO+"人");
			}
			Object joinPartyO =baseInfo.get("rdsj");
			if (joinPartyO != null) {
				Date joinParty = (Date) joinPartyO;
				sdf = new SimpleDateFormat("yyyy.MM");
				String jp = sdf.format(joinParty);
				sdf = null;
				person.setJoinPartyYear("，"+jp.substring(0,jp.indexOf('.'))+"年");
				person.setJoinPartyMonth(jp.substring(jp.indexOf('.')+1, jp.length())+"月加入中国共产党");
			}
			Object startWorkO = baseInfo.get("jobstartdate");
			if (startWorkO != null) {
				Date startWork = (Date) startWorkO;
				sdf = new SimpleDateFormat("yyyy.MM");
				String sw = sdf.format(startWork);
				sdf = null;
				person.setStartWorkYear("，"+sw.substring(0, sw.indexOf('.'))+"年");
				person.setStartWorkMonth(sw.substring(sw.indexOf('.')+1,sw.length())+"月参加工作");
			}
		}

		String profession = null;
		try {
			profession = PersonDataUtils.getTechnicalPostByPersonId(
					personId);
		} catch (BOSException e) {
			callChain += "查询跟人基本信息表职称数据的方法执行异常" + e;
			log.error(callChain);
			return null;
		}
		person.setProfession(profession);

		Map[] edu = null;
		try {
			edu = PersonDataUtils.getPersonDegreeByPersonId(personId);
		} catch (BOSException e) {
			callChain += "查询个人教育经历Map[]的方法执行异常：" + e;
			log.error(callChain);
			return null;
		}
		if (edu != null) {
			Map<String, Object> basicEdu = edu[1];
			Map<String, Object> vacationalEdu = edu[0];
			if (basicEdu != null) {
				Object diplomaO = basicEdu.get("diploma");
				String diplomaS = "";
				if(diplomaO!=null)diplomaS=diplomaO.toString();
				if(!"".equals(diplomaS))person.setEducationLevel("，"+diplomaS+"学历");		//学历
				Object degreeO = basicEdu.get("degree");
				if(degreeO!=null){
					String[] degreeSA=(String[])degreeO;
					String degree ="";
					for(String degreeS:degreeSA){
						degree += degreeS+"、";
					}
					
					if (!"".equals(degree)) {
						degree = degree.substring(0, degree.lastIndexOf("、"));
						person.setEducationTitle("，"+degree+"学位"); //学位
					}
				}
				Object majorO = basicEdu.get("schoolAndSpecialty");
				if(majorO!=null){
					String[] majorSA=(String[])majorO;
					String major="";
					for(String majorS:majorSA){
						major += majorS+"、";
					}
					if (!"".equals(major)) {
						major = major
								.substring(0, major.lastIndexOf("、"));
						person.setMajor("，"+major+"专业毕业");//毕业院校及专业
					}
				}
			}
			if (vacationalEdu != null) {
				Object vDiplomaO=vacationalEdu.get("diploma");
				String vDiplomaS = "";
				if(vDiplomaO!=null)vDiplomaS=vDiplomaO.toString();
				if(!"".equals(vDiplomaS))person.setVacationalLevel("，在职"+vDiplomaO.toString()+"学历");	//在职学历
				Object degreeO = vacationalEdu.get("degree");
				if(degreeO!=null){
					String[] degreeSA=(String[])degreeO;
					String degree ="";
					for(String degreeS:degreeSA){
						degree += degreeS+"、";
					}
					if (!"".equals(degree)) {
						degree = degree.substring(0, degree.lastIndexOf("、"));
						person.setVacationalTitle("，"+degree+"学位"); //在职学位
					}
				}
				Object vMajorO = vacationalEdu.get("schoolAndSpecialty");
				if(vMajorO!=null){
					String[] vMajorSA=(String[])vMajorO;
					String vMajor = "";
					for(String vMajorS:vMajorSA){
						vMajor += vMajorS+"<w:br/>";
					}
					if (!"".equals(vMajor)) {
						vMajor = vMajor.substring(0, vMajor
								.lastIndexOf("<w:br/>"));
						person.setVacationalMajor("，"+vMajor); //在职毕业院校及专业
					}
				}
			}
		}

		String position = null;
		try {
			position = PersonDataUtils.getNowJobByPersonId(personId);
		} catch (BOSException e) {
			callChain += "查询个人职务的方法执行异常：" + e;
			log.error(callChain);
			return null;
		}
		if (position != null) {
			person.setPosition(position);
		}

		LinkedList<Map<String, Object>> vitaeObj = null;
		try {
			vitaeObj = PersonDataUtils.getVitaeByPersonId(personId);
		} catch (BOSException e) {
			callChain += "查询个人简历的方法执行异常：" + e;
			log.error(callChain);
			return null;
		}
		List<Map<String, String>> vitaeStr = new ArrayList<Map<String, String>>();
		if (vitaeObj != null && vitaeObj.size() != 0) {
			int vitaeSize = vitaeObj.size();
			for (int i=0; i<vitaeSize; i++) {
				Map<String, Object> vitaObj = vitaeObj.get(i);
				Map<String, String> vitaStr = new HashMap<String, String>(2);
				String content = getVitaStrMapFromVitaObjMap(vitaObj);
				//如果是最后一个简历则补。号，否则补；号
				if(i==vitaeSize-1){
					content+="。";
				}else{
					content+="；";
				}
				vitaStr.put("content", content);
				vitaeStr.add(vitaStr);
			}
		} else {// 无vitae数据：补""值
			Map<String, String> vitaStr = new HashMap<String, String>(2);
			vitaStr.put("content", "");
			vitaeStr.add(vitaStr);
		}
		person.setVitae(vitaeStr);

		return person;
	}

	/**
	 * 根据人员personId实例化实体类HRTransferForm4Cadre的方法
	 * 
	 * @param personId
	 * @param callChain
	 * @return 如果出错则返回null，错误信息会记录到日志中
	 */
	public HRTransferForm4Cadre makeHRTransferForm4Cadre(Context ctx,
			String personId, Boolean isFutureDuty, String callChain) {
		if (callChain == null)
			callChain = "";
		callChain += "根据人员personId实例化实体类HRTransferForm4Cadre的方法：";

		if (StringUtils.isEmpty(personId)) {
			callChain += "员工内码personId参数为null或空";
			log.error(callChain);
			return null;
		}

		HRTransferForm4Cadre cadre = new HRTransferForm4Cadre();

		Map<String, Object> baseInfo = null;
		try {
			baseInfo = PersonDataUtils.getPersonBaseInfoById(personId);
		} catch (BOSException e) {
			callChain += "查询干部任免表实体类个人基本数据的方法执行异常：" + e;
			log.error(callChain);
			return null;
		}
		;
		SimpleDateFormat sdf = null;
		if (baseInfo != null) {
			// TODO: NPE check
			if (baseInfo.get("name") != null) {
				cadre.setName((String) baseInfo.get("name"));
			} else {
				cadre.setName("");
			}
			cadre
					.setGender(("1".equals(baseInfo.get("gender").toString())) ? "男"
							: "女");

			Date birth = null;
			if (baseInfo.get("birthday") != null) {
				birth = (Date) baseInfo.get("birthday");

				sdf = new SimpleDateFormat("yyyy.MM");
				String Birth = sdf.format(birth);
				int age = getAge(birth, callChain);
				String Age = age == -1 ? "" : (age + "");
				String birthDay = Birth + "<w:br/>（" + Age + "）";
				cadre.setBirthDay(birthDay);
			}

			// 民族
			if (baseInfo.get("folk") != null) {
				cadre.setEthnicity((String) baseInfo.get("folk"));
			} else {
				cadre.setEthnicity("");
			}
			// 籍贯
			if (baseInfo.get("nativeplace") != null) {
				cadre.setNativePlace((String) baseInfo.get("nativeplace"));
			} else {
				cadre.setNativePlace("");
			}
			// 出生地
			if (baseInfo.get("homeplace") != null) {
				cadre.setHomePlace((String) baseInfo.get("homeplace"));
			} else {
				cadre.setHomePlace("");
			}

			// sdf = new SimpleDateFormat("yyyy.MM");
			// 入党时间
			String rdsj = "";
			if (baseInfo.get("rdsj") != null) {
				rdsj = sdf.format((Date) baseInfo.get("rdsj"));
			}
			cadre.setJoinPartyTime(rdsj);

			// 健康状况
			if (baseInfo.get("health") != null) {
				cadre.setHealthCondition((String) baseInfo.get("health"));
			} else {
				cadre.setHealthCondition("");
			}

			String jobstartdate = "";

			if (baseInfo.get("jobstartdate") != null) {
				jobstartdate = sdf.format((Date) baseInfo.get("jobstartdate"));
			}

			cadre.setStartWorkTime(jobstartdate);
		}
		//职称
		String profession = null;
		try {
			profession = PersonDataUtils.getTechnicalPostByPersonId(
					personId);
		} catch (BOSException e) {
			callChain += "查询干部任免表职称数据的方法执行异常" + e;
			log.error(callChain);
			return null;
		}
		cadre.setProfession(profession);

		Map[] edu = null;
		try {
			edu = PersonDataUtils.getPersonDegreeByPersonId(ctx, personId);
		} catch (BOSException e) {
			callChain += "查询干部教育经历Map[]的方法执行异常：" + e;
			log.error(callChain);
			return null;
		}
		if (edu != null) {
			Map<String, Object> basicEdu = edu[1];
			Map<String, Object> vacationalEdu = edu[0];
			if (basicEdu != null) {
				Object diplomaO = basicEdu.get("diploma");
				if(diplomaO!=null)cadre.setEducationLevel(diplomaO.toString());		//学历
				Object degreeO = basicEdu.get("degree");
				if(degreeO!=null){
					String[] degreeSA=(String[])degreeO;
					String degree ="";
					for(String degreeS:degreeSA){
						degree += degreeS+"、";
					}
					if (!"".equals(degree)) {
						degree = degree.substring(0, degree.lastIndexOf("、"));
						cadre.setEducationTitle(degree); //学位
					}
				}
				Object majorO = basicEdu.get("schoolAndSpecialty");
				if(majorO!=null){
					String[] majorSA=(String[])majorO;
					String major="";
					for(String majorS:majorSA){
						major += majorS+"<w:br/>";
					}
					if (!"".equals(major)) {
						major = major
								.substring(0, major.lastIndexOf("<w:br/>"));
						cadre.setMajor(major);//毕业院校及专业
					}
				}
			}
			if (vacationalEdu != null) {
				Object vDiplomaO=vacationalEdu.get("diploma");
				if(vDiplomaO!=null)cadre.setVacationalLevel(vDiplomaO.toString());	//在职学历
				Object degreeO = vacationalEdu.get("degree");
				if(degreeO!=null){
					String[] degreeSA=(String[])degreeO;
					String degree ="";
					for(String degreeS:degreeSA){
						degree += degreeS+"、";
					}
					if (!"".equals(degree)) {
						degree = degree.substring(0, degree.lastIndexOf("、"));
						cadre.setVacationalTitle(degree); //在职学位
					}
				}
				Object vMajorO = vacationalEdu.get("schoolAndSpecialty");
				if(vMajorO!=null){
					String[] vMajorSA=(String[])vMajorO;
					String vMajor = "";
					for(String vMajorS:vMajorSA){
						vMajor += vMajorS+"<w:br/>";
					}
					if (!"".equals(vMajor)) {
						vMajor = vMajor.substring(0, vMajor
								.lastIndexOf("<w:br/>"));
						cadre.setVacationalMajor(vMajor); //在职毕业院校及专业
					}
				}
			}
		}

		if (isFutureDuty) {
			Map<String, String> nowAndFutureDuty;
			try {
				nowAndFutureDuty = PersonDataUtils
						.getNowAndFatureJobByPersonId(personId);
			} catch (BOSException e) {
				callChain += "查询干部现任和拟任职务的方法执行异常：" + e;
				log.error(callChain);
				return null;
			}
			if (nowAndFutureDuty != null) {
				cadre.setCurrentDuty(nowAndFutureDuty.get("nowJob"));
				cadre.setProposedDuty(nowAndFutureDuty.get("fatureJob"));
			}

		} else {
			String currentDuty = null;
			try {
				currentDuty = PersonDataUtils.getNowJobByPersonId(personId);
			} catch (BOSException e) {
				callChain += "查询干部现任职务的方法执行异常：" + e;
				log.error(callChain);
				return null;
			}
			if (currentDuty != null) {
				cadre.setCurrentDuty(currentDuty);
			}
		}

		LinkedList<Map<String, Object>> vitaeObj = null;
		try {
			vitaeObj = PersonDataUtils.getVitaeByPersonId(personId);
		} catch (BOSException e) {
			callChain += "查询干部简历的方法执行异常：" + e;
			log.error(callChain);
			return null;
		}
		List<Map<String, String>> vitaeStr = new ArrayList<Map<String, String>>();
		if (vitaeObj != null && vitaeObj.size() != 0) {
			for (Map<String, Object> vitaObj : vitaeObj) {
				Map<String, String> vitaStr = new HashMap<String, String>(2);
				String content = getVitaStrMapFromVitaObjMap(vitaObj);
				vitaStr.put("content", content);
				vitaeStr.add(vitaStr);
			}
		} else {// 无vitae数据：补""值
			Map<String, String> vitaStr = new HashMap<String, String>(2);
			vitaStr.put("content", "");
			vitaeStr.add(vitaStr);
		}
		cadre.setVitae(vitaeStr);

		List<Map<String, Object>> rewardPunish = null;
		try {
			rewardPunish = PersonDataUtils.getRewardPunish(ctx, personId);
		} catch (BOSException e) {
			callChain += "查询干部奖惩情况的方法执行异常：" + e;
			log.error(callChain);
			return null;
		}
		List<Map<String, String>> rewardPenalty = new ArrayList<Map<String, String>>();
		if (rewardPunish != null && rewardPunish.size() != 0) {
			for (Map<String, Object> rpObj : rewardPunish) {
				Map<String, String> rpStr = new HashMap<String, String>(2);
				String date, rp;
				sdf = new SimpleDateFormat("yyyy.MM");
				date = sdf.format(rpObj.get("occurDate"));
				sdf = null;
				rp = (String) rpObj.get("content");
				String content = date + "  " + rp;
				rpStr.put("content", content);
				rewardPenalty.add(rpStr);
			}
		} else {// 无奖惩数据：补""值
			Map<String, String> rpStr = new HashMap<String, String>(2);
			rpStr.put("content", "");
			rewardPenalty.add(rpStr);
		}
		cadre.setRewardAndPenalty(rewardPenalty);

		List<Map<String, String>> yearRes = null;
		try {
			yearRes = PersonDataUtils.getNDKH(personId);
		} catch (BOSException e) {
			callChain += "查询干部年度考核结果的方法执行异常：" + e;
			log.error(callChain);
			return null;
		}
		List<Map<String, String>> annualResults = new ArrayList<Map<String, String>>();
		if (yearRes != null && yearRes.size() != 0) {
			for (Map<String, String> yr : yearRes) {
				Map<String, String> annualResult = new HashMap<String, String>(
						2);
				String content = yr.get("year") + " - " + yr.get("res");
				annualResult.put("content", content);
				annualResults.add(annualResult);
			}
		} else {// 无年度审核结果数据：补""值
			Map<String, String> annualResult = new HashMap<String, String>(2);
			annualResult.put("content", "");
			annualResults.add(annualResult);
		}
		cadre.setAnnualResult(annualResults);

		List<Map<String, Object>> personFamily = null;
		try {
			personFamily = PersonDataUtils.getPersonFamily(ctx, personId);
		} catch (BOSException e) {
			callChain += "查询干部家庭及社会关系列表的方法执行异常：" + e;
			log.error(callChain);
			return null;
		}
		List<Map<String, String>> familyRelative = new ArrayList<Map<String, String>>();
		if (personFamily != null && personFamily.size() != 0) {
			for (Map<String, Object> relObj : personFamily) {
				Map<String, String> relStr = new HashMap<String, String>(8);
				String name = "";
				String workunit = "";
				String relationship = "";
				String face = "";
				Date birthday = null;
				// TODO: NPE
				if (relObj.get("name") != null) {
					name = (String) relObj.get("name");
				}

				if (relObj.get("birthday") != null) {
					birthday = (Date) relObj.get("birthday");
				}

				int age_ = getAge(birthday, callChain);

				if (relObj.get("workUnit") != null) {
					workunit = (String) relObj.get("workUnit");
				}

				if (relObj.get("relation") != null) {
					relationship = (String) relObj.get("relation");
				}

				if (relObj.get("politicalFace") != null) {
					face = (String) relObj.get("politicalFace");
					int lenF = face.length();
					if (lenF>3) {
						String face1 = face.substring(0, 2);
						String face2 = face.substring(2, lenF);
						face = face1 + "<w:br/>" + face2;
					}
				}

				relStr.put("relationship", relationship);
				relStr.put("name", name);
				relStr.put("age", (age_ == -1) ? "" : (age_ + ""));
				relStr.put("party", face);
				relStr.put("job", workunit);

				familyRelative.add(relStr);
			}
			int frSize=familyRelative.size();
			if(frSize<6){
				int toAdd = 6-frSize;
				// 家庭成员及社会关系数据不满6行：补""值
				Map<String, String> relStr = new HashMap<String, String>(8);
				relStr.put("relationship", "");
				relStr.put("name", "");
				relStr.put("age", "");
				relStr.put("party", "");
				relStr.put("job", "");
				// 家庭成员保持6行
				familyRelative.add(relStr);
				for(int i=0;i<toAdd;i++){
					familyRelative.add(relStr);
				}
			}
		} else {// 无家庭成员及社会关系数据：补""值
			Map<String, String> relStr = new HashMap<String, String>(8);
			relStr.put("relationship", "");
			relStr.put("name", "");
			relStr.put("age", "");
			relStr.put("party", "");
			relStr.put("job", "");
			// 家庭成员保持6行空白行
			familyRelative.add(relStr);
			familyRelative.add(relStr);
			familyRelative.add(relStr);
			familyRelative.add(relStr);
			familyRelative.add(relStr);
			familyRelative.add(relStr);
		}
		cadre.setFamilyAndRelatives(familyRelative);

		sdf = null;
		
		return cadre;
	}

	/**
	 * 将值为Object类的多键值vita(简历)集合转化为值为String类的单键值对vita(简历)集合
	 * 
	 * @param vitaObj
	 * @return
	 */
	private String getVitaStrMapFromVitaObjMap(Map<String, Object> vitaObj) {
		String begin, end, vita;
		SimpleDateFormat sdf;
		sdf = new SimpleDateFormat("yyyy.MM");
		begin = sdf.format(vitaObj.get("begintime"));
		sdf = null;
		sdf = new SimpleDateFormat("yyyy.MM");
		end = sdf.format(vitaObj.get("endtime"));
		sdf = null;
		vita = (String) vitaObj.get("vita");
		String content = begin + "--" + end + "  " + vita;
		return content;
	}

	/**
	 * 根据生日计算今年年龄
	 * 
	 * @param birthDay
	 * @return 如果出错则返回-1
	 */
	private int getAge(Date birthDay, String callChain) {
		if (callChain == null)
			callChain = "";
		callChain += "根据生日日期类实例计算今年年龄的方法：";
		if (birthDay == null) {
			callChain += "生日日期实例birthDay参数为null";
			log.error(callChain);
			return -1;
		}
		Calendar cal = Calendar.getInstance();
		if (cal.before(birthDay)) {
			throw new IllegalArgumentException(
					"The birthDay is before Now.It's unbelievable!");
		}
		int yearNow = cal.get(Calendar.YEAR);
		int monthNow = cal.get(Calendar.MONTH);
		int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
		cal.setTime(birthDay);

		int yearBirth = cal.get(Calendar.YEAR);
		int monthBirth = cal.get(Calendar.MONTH);
		int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

		int age = yearNow - yearBirth;

		if (monthNow <= monthBirth) {
			if (monthNow == monthBirth) {
				if (dayOfMonthNow < dayOfMonthBirth)
					age--;
			} else {
				age--;
			}
		}
		return age;
	}

}
